// NFC_01 [OpenGLWindow].nova



// Using namespace declarations.
using Library.NFC;
using Library.OpenGL;



// The application class.
class OpenGLWindowApp
{
   // Static data members.
   private static OpenGLWindow window;



   // Application class's "main" function.
   public static void main( String[] args )
   {
      Stream.writeLine( "Start" );


      // Create a new OpenGL window.
      window = new OpenGLWindow( "NFC_01 [OpenGLWindow]", 640, 480 );

      // Initialize OpenGL.
      initGL( );

      // Set the window's static callback methods.
      window.setSizeCallback( sizeScene );
      window.setPaintCallback( paintScene );

      // Show the window.
      window.show( true );

      // Process the window's events.
      window.processEvents( );


      Stream.writeLine( "End" );
   }



   // Initialize OpenGL.
   private static void initGL( )
   {
      // Initialize OpenGL.
      OpenGL.glShadeModel( OpenGL.GL_SMOOTH );
      OpenGL.glClearDepth( 1.0 );
      OpenGL.glEnable( OpenGL.GL_DEPTH_TEST );
   }



   // Window resize static callback.
   private static void sizeScene( Component sender, int sizeX, int sizeY )
   {
      Stream.writeLine( "sizeCallback: " + Integer.toString( sizeX ) + ", " + Integer.toString( sizeY ) );


      // Prevent a divide by zero error.
      if ( sizeY == 0 )
      {
         // Set the height equal to one.
         sizeY = 1;
      }

      // Reset the current viewport.
      OpenGL.glViewport( 0, 0, sizeX, sizeY );

      // Select the projection matrix.
      OpenGL.glMatrixMode( OpenGL.GL_PROJECTION );
      // Reset the projection matrix.
      OpenGL.glLoadIdentity( );

      // Calculate the aspect ratio of the window.
      OpenGL.gluPerspective( 45.0, (double)sizeX / (double)sizeY, 0.1, 100.0 );

      // Select the modelview matrix.
      OpenGL.glMatrixMode( OpenGL.GL_MODELVIEW );
      // Reset the modelview matrix.
      OpenGL.glLoadIdentity( );
   }



   // Window paint static callback.
   private static void paintScene( Component sender )
   {
      Stream.writeLine( "paintScene" );


      // Clear the buffers.
      OpenGL.glClear( OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT );

      // Reset the current matrix.
      OpenGL.glLoadIdentity( );

      // Move into the scene.
      OpenGL.glTranslatef( 0.0f, 0.0f, -4.0f );

      // Draw a triangle.
      OpenGL.glBegin( OpenGL.GL_TRIANGLES );
         OpenGL.glColor3f(   0.0f,  0.0f, 1.0f );  // Blue.
         OpenGL.glVertex3f(  0.0f,  1.0f, 0.0f );  // Top
         OpenGL.glColor3f(   1.0f,  0.0f, 0.0f );  // Red.
         OpenGL.glVertex3f( -1.0f, -1.0f, 0.0f );  // Bottom left.
         OpenGL.glColor3f(   0.0f,  1.0f, 0.0f );  // Green.
         OpenGL.glVertex3f(  1.0f, -1.0f, 0.0f );  // Bottom right.
      OpenGL.glEnd( );

      // Swap the window's OpenGL buffers.
      window.swapBuffers( );
   }
}